矩陣(Matrix)是線性代數的基石,它在電腦圖學、機器學習、數據分析和物理學等眾多領域中都扮演著核心角色。對於程式開發者而言,理解矩陣運算不僅能幫助我們解決複雜的數學問題,還能讓我們更深入地掌握如 3D 變換、神經網路等技術的底層原理。
本篇文章將帶您從最基本的矩陣概念出發,介紹其運算規則,並結合數學公式與一個功能強大的 JavaScript 矩陣 類別,一步步學習如何在程式碼中實現並應用這些理論。
1. 什麼是矩陣?
矩陣是一個按橫列(row)和直行(column)排列的矩形數字陣列。一個擁有 $$m$$ 個橫列和 $$n$$ 個直行的矩陣被稱為 $$m \times n$$ 矩陣。
$$ A=\begin{pmatrix} a_{11} & a_{12} & \cdots & a_{1n} \ a_{21} & a_{22} & \cdots & a_{2n} \\ \vdots & \vdots & \ddots & \vdots \\ a_{m1} & a_{m2} & \cdots & a_{mn} \end{pmatrix} $$
在 JavaScript 中建立矩陣
在我們的 矩陣 類別中,有兩種主要的方式來建立一個矩陣物件:
透過指定維度建立: 給定橫列數和直行數,可選擇性地提供一個預設值來填滿矩陣。
透過二維陣列建立: 直接傳入一個陣列的陣列。
// 引入我們預先定義好的矩陣類別
import 矩陣 from './矩陣.js';
// 建立一個 2x3 的矩陣,所有元素預設為 0
const m1 = new 矩陣(2, 3);
console.log('2x3 矩陣:');
console.log(m1.轉為字串());
// 從一個現有的二維陣列建立矩陣
const m2 = new 矩陣( [1, 2, 3], [4, 5, 6] );
console.log('從陣列建立的矩陣:');
console.log(m2.轉為字串());
// 使用 .橫列數量 和 .直行數量 屬性來獲取維度
console.log(`m2 的維度: ${m2.橫列數量}x${m2.直行數量}`);
// m2 的維度: 2x3
2. 矩陣的基本運算規則
在深入程式碼實作之前,讓我們先了解矩陣運算的一些基本代數規則。
加法運算規則
矩陣加法符合交換律和結合律,與純量(單一數值)的加法規則相似。
交換律 (Commutative Law):$A + B = B + A$
結合律 (Associative Law):$(A + B) + C = A + (B + C)$
乘法運算規則
矩陣乘法比加法要特殊得多,最重要的一點是它不符合交換律。
不符合交換律 (Not Commutative): 絕大多數情況下,$$AB \neq BA$$。矩陣相乘的順序至關重要。
結合律 (Associative Law): $$(AB)C = A(BC)$$
分配律 (Distributive Laws): $$A(B + C) = AB + AC$$ $$(A + B)C = AC + BC$$
純量乘法規則
純量與矩陣的乘法符合分配律。 $$k(A + B) = kA + kB$$ $$(k + l)A = kA + lA$$
3. 在 JavaScript 中實現基本運算
矩陣加法與減法
兩個矩陣相加或相減的前提是它們必須具有相同的維度。運算方式是將對應位置的元素進行加減。
$$ 若 C = A + B , c_{ij} = a_{ij} + b_{ij} \ 若 D = A - B , d_{ij} = a_{ij} - b_{ij} $$
矩陣 類別提供了 加() 和 減() 方法來實現這些操作。
const A = new 矩陣([1, 2], [3, 4]);
const B = new 矩陣([5, 6], [7, 8]);
// 矩陣加法
const C = A.加(B);
console.log('A + B:');
console.log(C.轉為字串());
// 矩陣減法
const D = A.減(B);
console.log('A - B:');
console.log(D.轉為字串());
純量乘法
純量乘法是指將一個純量(即單一的數字)與矩陣中的每一個元素相乘。
$$\text{若 } B = kA \text{, 則 } b_{ij} = k \cdot a_{ij}$$
乘() 方法可以處理純量乘法。
const A = new 矩陣([1, 2], [3, 4]);
const k = 10;
// 純量乘法
const B = A.乘(k);
// 呼叫 乘(目標),目標為一個數字
console.log('10 * A:');
console.log(B.轉為字串());
4. 在 JavaScript 中實現進階運算
矩陣乘法
只有當第一個矩陣的直行數等於第二個矩陣的橫列數時,兩個矩陣才能相乘。若 $$A$$ 是 $$m \times n$$ 矩陣, $$B$$ 是 $$n \times p$$ 矩陣,則它們的乘積 $$C = AB$$ 將會是一個 $$m \times p$$ 矩陣。其元素計算公式為: $$c_{ij} = \sum_{k=1}^{n} a_{ik}b_{kj}$$
乘() 方法同樣支援矩陣與矩陣的乘法。
const A = new 矩陣([1, 2, 3], [4, 5, 6]);
// 2x3
const B = new 矩陣([7, 8], [9, 10], [11, 12]);
// 3x2
// 矩陣乘法
const C = A.乘(B);
// 2x3 矩陣乘以 3x2 矩陣,得到 2x2 矩陣
console.log('A * B:'); console.log(C.轉為字串());
轉置矩陣
轉置矩陣是將原矩陣的橫列與直行互換得到的。原矩陣 $A$ 的轉置記為 $A^T$。 $$\text{若 } A = [a_{ij}] \text{, 則 } A^T = [a_{ji}]$$
轉置矩陣() 方法可以輕鬆完成這個操作。
const A = new 矩陣([1, 2, 3], [4, 5, 6]);
// 2x3 const AT = A.轉置矩陣();
// 得到 3x2 矩陣
console.log('A 的轉置:');
console.log(AT.轉為字串());
行列式
行列式是一個與方塊矩陣相關的純量值,它包含了矩陣的重要資訊,例如矩陣所代表的線性變換對空間的縮放比例。若行列式為 0,則該矩陣不可逆。對於一個 $$2 \times 2$$ 矩陣,行列式計算如下:
$$ \det(A) = \begin{vmatrix} a & b \ c & d \end{vmatrix} = ad - bc $$
在我們的類別中,特徵值 屬性被用來計算行列式。
注意:儘管屬性名稱為
特徵值(Eigenvalue),但其內部實作是透過高斯消去法將矩陣化為上三角形式,再將主對角線元素相乘,這正是計算行列式(Determinant)的標準方法之一。
const A = new 矩陣([3, 1], [4, 2]);
// 計算行列式
const detA = A.特徵值; // 實際上是計算行列式
console.log(`A 的行列式: ${detA}`);
// 輸出: A 的行列式: 2 (3*2 - 1*4)
反矩陣
對於一個方塊矩陣 $$A$$,如果存在另一個矩陣 $$A^{−1}$$ 使得它們的乘積為單位矩陣 I,那麼 $$A^{−1}$$ 就被稱為 $$A$$ 的反矩陣。
$$AA^{−1}=A^{−1}A=I$$
只有當矩陣的行列式不為零時,其反矩陣才存在。矩陣 類別使用 反矩陣() 方法,透過高斯-喬登消去法來計算反矩陣。
const A = new 矩陣([4, 7], [2, 6]);
// 計算反矩陣
const A_inv = A.反矩陣();
console.log('A 的反矩陣:');
// 修正浮點數誤差後再輸出
console.log(A_inv.修正精確度誤差().轉為字串());
5. 特殊矩陣與實作
單位矩陣
單位矩陣 $$I$$ 是一個主對角線元素全為 1,其餘元素全為 0 的方塊矩陣。它在矩陣乘法中的作用相當於數字 1 在普通乘法中的作用。矩陣 類別提供了一個靜態方法 單位矩陣() 來快速生成它。
// 建立一個 3x3 的單位矩陣
const I = 矩陣.單位矩陣(3);
console.log('3x3 單位矩陣:');
console.log(I.轉為字串());
對稱與反對稱矩陣
對稱矩陣 (Symmetric Matrix): 如果一個方塊矩陣等於它自己的轉置 $$ A=A^{T} $$ 則稱其為對稱矩陣。
反對稱矩陣 (Antisymmetric Matrix): 如果一個方塊矩陣的轉置等於其自身的負矩陣 $$ A^{T}=−A $$,則稱其為反對稱矩陣。
類別中 是對稱矩陣() 和 是反對稱矩陣() 方法可以幫助我們進行判斷。
const sym = new 矩陣([1, 7, 3], [7, 4, -5], [3, -5, 6]);
const anti_sym = new 矩陣([0, 2, -1], [-2, 0, -4], [1, 4, 0]);
console.log(`sym 是對稱矩陣嗎? ${sym.是對稱矩陣()}`); // true
console.log(`anti_sym 是反對稱矩陣嗎? ${anti_sym.是反對稱矩陣()}`); // true
結論
透過本文的介紹,我們不僅學習了矩陣的核心數學概念與運算規則,還看到了如何將這些抽象的理論轉化為具體、可執行的 JavaScript 程式碼。擁有像 矩陣.js 這樣一個結構清晰、功能完備的類別,可以簡化我們在處理複雜數學問題時的開發工作。